﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Xml;
namespace HeavenvsDarkness
{

    public class MyCursor : VisibleGameEntity
    {
        private MouseState prevMouseState;

        public MouseState PrevMouseState
        {
            get { return prevMouseState; }
            set { prevMouseState = value; }
        }
        private MouseState currentMouseState;

        public MouseState CurrentMouseState
        {
            get { return currentMouseState; }
            set { currentMouseState = value; }
        }

        VisibleGameEntity _itemChoosen;

        public VisibleGameEntity ItemChoosen
        {
            get { return _itemChoosen; }
            set { _itemChoosen = value; }
        }

        Vector2 position2D;

        public Vector2 Position2D
        {
            get { return position2D; }
            set { position2D = value; }
        }

        event System.EventHandler MouseClick;
        event System.EventHandler MouseMove;
        event System.EventHandler MouseRightClick;
        public MyCursor()
        {
            Items = new List<VisibleGameEntity>();
            XmlDocument Doc = new XmlDocument();
            Doc.Load("ConfigureInterface.xml");

            XmlNode nodeCursor = Doc.SelectSingleNode("/Game/Cursor");
            XmlNodeList temp = nodeCursor.ChildNodes;
            XmlElement eleCursor = (XmlElement)temp[0];
            MySprite myCursor = new MySprite(eleCursor);
            Items.Add(myCursor);
            MouseClick += new EventHandler(MyCursor_MouseClick);
            MouseMove += new EventHandler(MyCursor_MouseMove);
            MouseRightClick += new EventHandler(MyCursor_MouseRightClick);
            Scale = float.Parse(eleCursor.GetAttribute("Scale"));

            Size = Scale * GetTextureSize();
            Viewport port = GameUtil.game.GraphicsDevice.Viewport;
            Vector2 tempPos;
            tempPos.X = port.X + port.Width / 2;
            tempPos.Y = port.Y + port.Height / 2;
            Position2D = tempPos;
        }

        void MyCursor_MouseRightClick(object sender, EventArgs e)
        {
            Global.BroastCastEvent(Global.EVENT.GM_MOUSE_RIGHTCLICKED, sender, e);
        }

        void MyCursor_MouseMove(object sender, EventArgs e)
        {
            Global.BroastCastEvent(Global.EVENT.GM_MOUSE_MOVE, sender, e);
        }

        void MyCursor_MouseClick(object sender, EventArgs e)
        {
          /*  if (ItemChoosen != null)
            {
                if ((ItemChoosen.GetType() == typeof(MyDefensePetInstance) && GameUtil.isHeavenForce) || (ItemChoosen.GetType() == typeof(MyAttackPetInstance) && !GameUtil.isHeavenForce))
                {
                    Global.BroastCastEvent(Global.EVENT.GM_CURSOR_CLICKEDTOPLACEPET, this, null);
                }
            }
            else*/
            {
                Global.BroastCastEvent(Global.EVENT.GM_MOUSE_CLICKED, sender, e);
            }
        }

        public override void Update(GameTime gameTime)
        {
            Vector2 temp;
            temp.X = CurrentMouseState.X;
            temp.Y = CurrentMouseState.Y;
            Position2D = temp;

            /*
            if (ItemChoosen != null)
            {
                if (GameUtil.isHeavenForce)
                {
                    if (ItemChoosen.GetType() == typeof(MyDefensePetInstance))
                    {
                        MyDefensePetInstance tempPet = (MyDefensePetInstance)ItemChoosen;
                        tempPet.Position = Position;
                        tempPet.UpdatePosition();
                    }
                }
                else
                {
                    if (ItemChoosen.GetType() == typeof(MyAttackPetInstance))
                    {
                        MyAttackPetInstance tempPet = (MyAttackPetInstance)ItemChoosen;
                        tempPet.Position = Position;
                        tempPet.UpdatePosition();
                    }
                }
            }*/



            if (isMouseClicked())
            {
                MyCursor_MouseClick(this, null);
            }

            if (isMouseMove())
            {
                MyCursor_MouseMove(this, null);
            }

            if (isMouseRightClicked())
            {
                MyCursor_MouseRightClick(this, null);
            }

        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Begin();
            if (ItemChoosen == null)
            {
                for (int i = Items.Count - 1; i >= 0; i--)
                {

                    //Model.Draw(Items[i].GetTexture(), graphicDevice, camera,Position);
                    //Items[i].Draw(graphicDevice, camera);
                    spriteBatch.Draw(Items[i].GetTexture(), new Rectangle((int)Position2D.X, (int)Position2D.Y, (int)Size.X, (int)Size.Y), Color.White);
                    
                }
            }
            else
            {
                ItemChoosen.Draw(spriteBatch);
            }
            spriteBatch.End();
        }

     
       
        public Boolean isScrollIncrease()
        {
            if (CurrentMouseState.ScrollWheelValue > PrevMouseState.ScrollWheelValue)
                return true;
            return false;
        }

        public Boolean isScrollDecrease()
        {
            if (CurrentMouseState.ScrollWheelValue < PrevMouseState.ScrollWheelValue)
                return true;
            return false;
        }

        public Boolean isMouseClicked()
        {
            if (CurrentMouseState.LeftButton == ButtonState.Released && PrevMouseState.LeftButton == ButtonState.Pressed)
                return true;
            return false;
        }

        public Boolean isMouseRightClicked()
        {
            if (CurrentMouseState.RightButton == ButtonState.Released && PrevMouseState.RightButton == ButtonState.Pressed)
                return true;
            return false;
        }

        public Boolean isMouseMove()
        {
            if (CurrentMouseState.X == PrevMouseState.X && CurrentMouseState.Y == PrevMouseState.Y)
            {
                return false;
            }
            return true;
        }

        public override bool OnEvent(Global.EVENT events, object sender, object arg)
        {
            switch (events)
            {
                case Global.EVENT.GM_MOUSE_RIGHTCLICKED:
                    ItemChoosen = null;
                    break;
            }
            return false;
        }

        public Ray CalculateCursorRay(Matrix projectionMatrix, Matrix viewMatrix)
        {
            // create 2 positions in screenspace using the cursor position. 0 is as
            // close as possible to the camera, 1 is as far away as possible.
            Vector3 nearSource = new Vector3(Position2D, 0f);
            Vector3 farSource = new Vector3(Position2D, 1f);

            // use Viewport.Unproject to tell what those two screen space positions
            // would be in world space. we'll need the projection matrix and view
            // matrix, which we have saved as member variables. We also need a world
            // matrix, which can just be identity.
            Vector3 nearPoint = GameUtil.graphicDevice.Viewport.Unproject(nearSource,
                projectionMatrix, viewMatrix, Matrix.Identity);

            Vector3 farPoint = GameUtil.graphicDevice.Viewport.Unproject(farSource,
                projectionMatrix, viewMatrix, Matrix.Identity);

            // find the direction vector that goes from the nearPoint to the farPoint
            // and normalize it....
            Vector3 direction = farPoint - nearPoint;
            direction.Normalize();

            // and then create a new ray using nearPoint as the source.
            return new Ray(nearPoint, direction);

        }

        public Ray GetPickRay()
        {
            Vector3 nearsource = new Vector3(Position2D, 0f);
            Vector3 farsource = new Vector3(Position2D, GameUtil.Camera.NearDistance);

            Vector3 nearPoint = GameUtil.graphicDevice.Viewport.Unproject(nearsource, GameUtil.Camera.Projection, GameUtil.Camera.View, Matrix.Identity);

            Vector3 farPoint = GameUtil.graphicDevice.Viewport.Unproject(farsource, GameUtil.Camera.Projection, GameUtil.Camera.View, Matrix.Identity);

            // Create a ray from the near clip plane to the far clip plane.
            Vector3 direction = farPoint - nearPoint;
            direction.Normalize();
            Ray pickRay = new Ray(nearPoint, direction);
            return pickRay;
        }

        public Vector3 GetPickedPosition()
        {

            // create 2 positions in screenspace using the cursor position. 0 is as
            // close as possible to the camera, 10 is as far away as possible
            Vector3 nearSource = new Vector3(Position2D, 0);
            Vector3 farSource = new Vector3(Position2D, GameUtil.Camera.NearDistance);
            // find the two screen space positions in world space
            Vector3 nearPoint = GameUtil.graphicDevice.Viewport.Unproject(nearSource,
                                GameUtil.Camera.Projection,
                                GameUtil.Camera.View, Matrix.Identity);

            Vector3 farPoint = GameUtil.graphicDevice.Viewport.Unproject(farSource,
                                GameUtil.Camera.Projection,
                                GameUtil.Camera.View, Matrix.Identity);

            // compute normalized direction vector from nearPoint to farPoint
            Vector3 direction = farPoint - nearPoint;
            direction.Normalize();

            // create a ray using nearPoint as the source
            Ray r = new Ray(nearPoint, direction);

            // calculate the ray-plane intersection point
            Vector3 n = new Vector3(0f, 0f, 1f);
            Plane p = new Plane(n, 0f);

            // calculate distance of intersection point from r.origin
            float denominator = Vector3.Dot(p.Normal, r.Direction);
            float numerator = Vector3.Dot(p.Normal, r.Position) + p.D;
            float t = -(numerator / denominator);

            // calculate the picked position on the y = 0 plane
            Vector3 pickedPosition = nearPoint + direction * t;

            return pickedPosition;
        }

       
    }
}
